/*
 * JavaAccess.java - ScriptME
 * 
 * Copyright (c) 2009 Cesar Henriques <cesar at alttab.com.ar>.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Based on FESI Project
 * 
 * Contributors:
 * 	Jean-Marc Lugrin - initial API and implementation
 * 	Cesar Henriques <cesar at alttab.com.ar> - J2ME Porting and Extensions
 */
package org.scriptme.ecmascript.ext;

import org.scriptme.ecmascript.data.BuiltinFunctionObject;
import org.scriptme.ecmascript.data.ESBeans;
import org.scriptme.ecmascript.data.ESBoolean;
import org.scriptme.ecmascript.data.ESLoader;
import org.scriptme.ecmascript.data.ESObject;
import org.scriptme.ecmascript.data.ESPackages;
import org.scriptme.ecmascript.data.ESString;
import org.scriptme.ecmascript.data.ESUndefined;
import org.scriptme.ecmascript.data.ESValue;
import org.scriptme.ecmascript.data.FunctionPrototype;
import org.scriptme.ecmascript.data.GlobalObject;
import org.scriptme.ecmascript.exceptions.EcmaScriptException;
import org.scriptme.ecmascript.interpreter.Evaluator;

/**
 * The Class JavaAccess.
 */
public class JavaAccess extends Extension {

	/**
	 * The Class GlobalObjectJavaTypeOf.
	 */
	class GlobalObjectJavaTypeOf extends BuiltinFunctionObject {

		/**
		 * Instantiates a new global object java type of.
		 * 
		 * @param name
		 *            the name
		 * @param evaluator
		 *            the evaluator
		 * @param fp
		 *            the fp
		 */
		GlobalObjectJavaTypeOf(String name, Evaluator evaluator,
				FunctionPrototype fp) {
			super(fp, evaluator, name, 1);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.scriptme.ecmascript.data.FunctionPrototype#callFunction(org.scriptme.ecmascript.data.ESObject,
		 *      org.scriptme.ecmascript.data.ESValue[])
		 */
		public ESValue callFunction(ESObject thisObject, ESValue[] arguments)
				throws EcmaScriptException {

			if (arguments.length > 0) {
				Object obj = arguments[0].toJavaObject();
				String cn = (obj == null) ? "null" : ESLoader.typeName(obj
						.getClass());
				return new ESString(cn);
			}
			return ESUndefined.theUndefined;
		}
	}

	/**
	 * The Class GlobalObjectLoadExtension.
	 */
	class GlobalObjectLoadExtension extends BuiltinFunctionObject {

		/**
		 * Instantiates a new global object load extension.
		 * 
		 * @param name
		 *            the name
		 * @param evaluator
		 *            the evaluator
		 * @param fp
		 *            the fp
		 */
		GlobalObjectLoadExtension(String name, Evaluator evaluator,
				FunctionPrototype fp) {
			super(fp, evaluator, name, 1);
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.scriptme.ecmascript.data.FunctionPrototype#callFunction(org.scriptme.ecmascript.data.ESObject,
		 *      org.scriptme.ecmascript.data.ESValue[])
		 */
		public ESValue callFunction(ESObject thisObject, ESValue[] arguments)
				throws EcmaScriptException {

			Object ext = null;
			if (arguments.length > 0) {
				String pathName = arguments[0].toString();
				ext = this.evaluator.addExtension(pathName);
			}
			return ESBoolean.makeBoolean(ext != null);
		}
	}

	/** The evaluator. */
	private Evaluator evaluator = null;

	/**
	 * Instantiates a new java access.
	 */
	public JavaAccess() {
		super();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.scriptme.ecmascript.ext.Extension#initializeExtension(org.scriptme.ecmascript.interpreter.Evaluator)
	 */
	public void initializeExtension(Evaluator evaluator)
			throws EcmaScriptException {
		this.evaluator = evaluator;

		GlobalObject go = evaluator.getGlobalObject();
		FunctionPrototype fp = (FunctionPrototype) evaluator
				.getFunctionPrototype();

		go.putHiddenProperty("javaTypeOf", new GlobalObjectJavaTypeOf(
				"javaTypeOf", evaluator, fp));
		go.putHiddenProperty("loadExtension", new GlobalObjectLoadExtension(
				"loadExtension", evaluator, fp));

		ESPackages packagesObject = (ESPackages) evaluator.getPackageObject();
		String java = ("java").intern();
		ESPackages javaPackages = (ESPackages) packagesObject.getProperty(java,
				java.hashCode());
		go.putHiddenProperty("Packages", packagesObject);
		go.putHiddenProperty(java, javaPackages);
		ESBeans javaBeans = new ESBeans(evaluator);
		go.putHiddenProperty("Beans", javaBeans);
	}
}
